﻿using System;
using System.Management.Automation;
using Microsoft.ResourceManagement.ObjectModel;
using Microsoft.ResourceManagement.Client;
using System.Collections;
using System.Collections.Generic;

namespace Quest.FIMPowerShellSnapin
{
    [Cmdlet(VerbsCommon.New, Constants.Nouns.FIMResource, SupportsShouldProcess = true)]
    public class NewIlmResource : PSCmdlet
    {
        private const string AttributesParamName = "Attributes";
        private String _type;
        private FIMPSResource _instance;
        private Hashtable _attributes;
        private bool _passThru;
        private FIMPSSession _session;

        [Parameter(Mandatory = true, ParameterSetName = "Type", ValueFromPipelineByPropertyName = true)]
        [ValidateNotNullOrEmpty]
        public String Type
        {
            get { return _type; }
            set { _type = value; }
        }

        [Parameter(Mandatory = true, ParameterSetName = "Instance", ValueFromPipeline = true)]
        [ValidateNotNullOrEmpty]
        public FIMPSResource Instance
        {
            get { return _instance; }
            set { _instance = value; }
        }

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [ValidateNotNullOrEmpty]
        public Hashtable Attributes
        {
            get { return _attributes; }
            set { _attributes = value; }
        }

        [Parameter]
        public SwitchParameter PassThru
        {
            get { return (SwitchParameter)_passThru; }
            set { _passThru = (bool)value; }
        }

        [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
        [ValidateNotNullOrEmpty]
        public FIMPSSession Session
        {
            get { return _session; }
            set { _session = value; }
        }

        protected override void ProcessRecord()
        {

            RmResource newObject = new RmResource();

            // Initialize a new resource object either by specifying it's ObjectType, or by assigning it the
            // all the attribute values from a resource object specified on the command line.
            switch (ParameterSetName)
            {
                case "Type":
                    // RmAttributeValue assignment semantics add values to an existing value, even if the attribute type
                    // is single-valued. To avoid multiple ObjectType values, we first remove the existing value for 
                    // ObjectType, and then set it to the new value.
                    newObject.ObjectType = null;
                    newObject.ObjectType = _type;
                    break;

                case "Instance":
                    newObject = _instance.Resource; //!!! verify this does the right thing.
                    break;

                default:
                    throw new Exception(Constants.Messages.InternalError_UnknownParameterSet);
            }

            // Sets additional attribute values specified by the hashtable from the Attributes command line parameter. Note that the
            // semantics are to overwrite any existing values, even if they are multi-valued.
            foreach (KeyValuePair<RmAttributeName, RmAttributeValue> attr in new AttributeHashtable(_attributes))
            {
                RmAttributeValue oldValue = null;

                if (newObject.TryGetValue(attr.Key, out oldValue))
                {
                    newObject[attr.Key] =  attr.Value;
                }
                else
                {
                    newObject.Add(attr.Key, attr.Value);
                }
            }

#if false //!!!fix
            bool shouldProcess = CmdletCommons.ShouldProcess(
                this, Messages.VerboseNew, Messages.ConfirmNew, rmObject);

            if (shouldProcess)
            {
                var conFactory = new ConnectionFactory(session, SessionState);

                WSTransferClient transferClient =
                    new WSTransferClient(conFactory, this.session.SchemaMgr);

                String newId = transferClient.Create(rmObject);

                if (passThru)
                {
                    rmObject.SetOneValueOfAttributeWithoutHistory(
                        WsClient.Constants.AttributeTypeObjectId,
                        newId,
                        this.session.SchemaMgr.AttributeFactory);

                    WriteObject(new ILMResource(rmObject, this.session));
                }
            }
#endif
            RmReference newObjectID = _session.Client.Create(newObject);
            if (_passThru) // N.B. the ObjectID of newObject is set by the call to Create()
            {
                WriteObject(new FIMPSResource(newObject, _session));
            }
        }
    }
}
